const tools = require("./pub/tools");
//用于全局事件统一分发。。需人为控制事件订阅风暴
class Hook{
    constructor(){
        this._data = {};
    }

    append( hookName , params , isSoon ){
        isSoon = tools.select(isSoon , false);
        if(!hookName || !params) return;
        params.active = true;
        this._data[hookName] = this._data[hookName] || [];
        this._data[hookName].push( params );

        isSoon && this.run(hookName);
    }

    appendUpdate( params ){
        if(!params) return;
        params.active = true;
        this._data.updates.push( params )
    }

    remove(){

    }

    // {
    //     active : true ,
    //     handler : function,
    //     params : handler的参数,
    //     check : function , 用户检查是否销毁
    //     destory : function, //销毁逻辑 
    //     once : true //是否只执行一次,
    //     time : 3 //定时执行多少秒
    // }
    //执行update钩子
    runUpdates( dt ){
        let updates = this._data.updates;
        let  remove=0;
        for(let i=0; i<updates.length; i++){
            let param = updates[i];
            if( param.active && param && param.handler){
                if( param.isPromise ){

                }else{
                    param._resout = param.handler( dt , param.params );

                    if( param.time ){
                        param._timer = param._timer ? param._timer+dt : dt;
                        if( param._timer>= param.time ){
                            param.destory && param.destory();
                            param.active = false;
                            remove += 1;
                        }
                    }

                    if( param.check ){
                       if( param.check( param._resout ) ){
                           param.destory && param.destory();
                           param.active = false;
                           remove += 1;
                       }
                    }else if( param.once){
                        param.destory && param.destory();
                        param.active = false;
                        remove += 1;
                    }
                }
            }
        }

        let i=0;
        while(i < this._data.updates.length){
            if(!this._data.updates[i]){
                this._data.updates.splice( i , 1);
            }else{
                i++;
            }
        }
    }

    run( hookName ){
        if(!this._data[hookName]) return;

        let handlers = this._data[hookName] || [];
        let args = Array.prototype.slice.call(arguments , 1),
            remove = 0;

        for(let i=0; i<handlers.length; i++){
            let param = handlers[i];
            if( param.active && param && param.handler ){
                if( param.checkrun &&  !param.checkrun(param) ){
                    continue;
                }
                if( param.isPromise ){

                }else{
                    let newargs = args.concat( param.params ? (tools.isType(param.params,"Array") ? param.params : [param.params]) : [] );
                    param._resout = param.handler( ...newargs );

                    if( param.time ){
                        param._timer = param._timer ? param._timer+dt : dt;
                        if( param._timer>= param.time ){
                            param.destroy && param.destroy();
                            param.active = false;
                            remove += 1;
                        }
                    }

                    if( param.check ){
                       if( param.check( param._resout ) ){
                           param.destroy && param.destroy();
                           param.active = false;
                           remove += 1;
                       }
                    }else if( param.once){
                        param.destroy && param.destroy();
                        param.active = false;
                        remove += 1;
                    }
                }
            }
        }

        let i=0;
        while(i < this._data[hookName].length){
            if( !this._data[hookName][i] || !this._data[hookName][i].active ){
                this._data[hookName].splice( i , 1);
            }else{
                i++;
            }
        }
    }
    
}

module.exports = Hook; 